﻿using System;
using System.Windows.Forms;
using System.Threading;
using Business.Entities;
using Business.Logic;
using Business;
using System.Drawing;

namespace GogTasks
{
    public partial class AuthForm : Form
    {
        private delegate void VoidEmptySignature();
        private string _username;
        private string _password;
        private string _appsDomain;
        private bool _isAppsAccount;


        public AuthForm(string username)
        {
            InitializeComponent();
            if (username != null)
            {
                UsernameTextBox.Text = username;
                AppsCheckBox.Checked = MobileContext.Config.IsGoogleAppsAccount;
                AppsDomainTextBox.Text = MobileContext.Config.GoogleAppsDomain;
            }
            SetColors();
        }

        private void AuthButton_Click(object sender, EventArgs e)
        {
            AuthenticateAsync();
        }

        private void AuthenticateAsync()
        {
            if (UsernameTextBox.Text.Length == 0) return;
            if (PasswordTextBox.Text.Length == 0) return;
            AuthButton.Enabled = false;
            //CancelButton.Enabled = false;
            AuthMenuButton.Enabled = false;
            CancelMenuButton.Enabled = false;
            keyboard.Enabled = false;
            _username = UsernameTextBox.Text;
            _password = PasswordTextBox.Text;
            _appsDomain = AppsDomainTextBox.Text;
            _isAppsAccount = AppsCheckBox.Checked;
            Thread t1 = new Thread(Authenticate);
            t1.Start();
        }

        private void Authenticate()
        {
            GoogleLogin gl = null;
            GoogleLogin.LoginResult loginResult = GoogleLogin.LoginResult.Unknown;
            Exception ex = null;
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                gl = new GoogleLogin();
                gl.IsGoogleAppsAccount = _isAppsAccount;
                gl.GoogleAppsDomain = _appsDomain;
                loginResult = gl.Login(_username, _password);
                Cursor.Current = Cursors.Default;
            }
            catch (Exception ex1)
            {
                ex = ex1;
            }
            Invoke(new AuthDoneDelegate(AuthenticateDone), new object[] { loginResult, gl,ex });
        }

        private delegate void AuthDoneDelegate(GoogleLogin.LoginResult loginResult, GoogleLogin googleLogin, Exception ex);

        private void AuthenticateDone(GoogleLogin.LoginResult loginResult, GoogleLogin googleLogin, Exception ex)
        {
            if (ex != null)
            {
                if (ex is AccountsRecoveryPromptException)
                {
                    MessageBox.Show("Google is prompting you to update your account recovery information. Please login to your GMail account from a web browser and update this information before returning to GogTasks.", "Unable to log in", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                }
                else
                {
                    //MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace, "Communication error");
                    var ef = new ErrorForm(googleLogin.ErrorPackage);
                    ef.ShowDialog(ex);
                }
            }
            else if (loginResult == GoogleLogin.LoginResult.WrongUsernameOrPass)
            {
                MessageBox.Show("Wrong username or password", "Authentication failed");
            }
            else if (loginResult == GoogleLogin.LoginResult.TuringTest)
            {
                MessageBox.Show("Login attempt hit turing test. Please go to " +
                    "calendar.google.com and log in manually before returning to " +
                    "this application for another attempt.", "Authentication failed");
            }
            else if (loginResult == GoogleLogin.LoginResult.Unknown)
            {
                MessageBox.Show("Login failed for unknown reason. Retry or restart " +
                    "application and/or phone and retry.", "Authentication failed");
            }
            else if (loginResult == GoogleLogin.LoginResult.Ok)
            {
                // Save cookies and wipe history for previous user, and we're done
                MobileContext.Config.Cookies = googleLogin.Cookies;
                MobileContext.Config.Username = _username;
                MobileContext.Config.IsGoogleAppsAccount = _isAppsAccount;
                MobileContext.Config.GoogleAppsDomain = _appsDomain;
                SyncHistory.Wipe();
                _authSuccessful = true;
            }
            else MessageBox.Show("Unknown result code from Login()");
            EnableButtonsAndClose();
        }

        private bool _authSuccessful = false;

        private void EnableButtonsAndClose()
        {
            Cursor.Current = Cursors.Default;
            AuthButton.Enabled = true;
            //CancelButton.Enabled = true;
            AuthMenuButton.Enabled = true;
            CancelMenuButton.Enabled = true;
            if (_authSuccessful) Close();
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            keyboard.Enabled = false;
            Close();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.DrawRectangle(new Pen(Color.Blue), 0, 0, Width-1, Height-1);
        }

        private void menuItem2_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void menuItem1_Click(object sender, EventArgs e)
        {
            keyboard.Enabled = false;
            AuthenticateAsync();
        }

        private void AppsCheckBox_CheckStateChanged(object sender, EventArgs e)
        {
            AppsDomainTextBox.Enabled = AppsCheckBox.Checked;
            SetColors();
        }

        private void SetColors()
        {
            if (AppsDomainTextBox.Enabled)
                AppsDomainTextBox.BackColor = UsernameTextBox.BackColor;
            else
                AppsDomainTextBox.BackColor = Color.FromArgb(240, 240, 240);
        }
    }
}